package org.ntu.rtsearch.index;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.ntu.rtsearch.analysis.Analyzer;
import org.ntu.rtsearch.analysis.SimpleAnalyzer;
import org.ntu.rtsearch.analysis.TokenStream;
import org.ntu.rtsearch.index.model.Document;
import org.ntu.rtsearch.index.model.Field;
import org.ntu.rtsearch.index.model.InvertedIndex;
import org.ntu.rtsearch.index.model.Posting;

public class SingleIndexWriter extends IndexWriter {

	private Analyzer analyzer = new SimpleAnalyzer();

	private InvertedIndex index = new InvertedIndex();

	@Override
	public void addDocument(Document doc) throws Exception {
		// generate index, add to the inverted index
		for (Field field : doc.getFields().values()) {
			// field info process
			Integer fieldId = index.getFieldNum(field.getName());

			// get position info
			Map<String, List<Integer>> positionInfoMap = getPositonInfo(field
					.getValue());
			postingCount += positionInfoMap.size();

			// add postings to the inverted index
			for (Map.Entry<String, List<Integer>> entry : positionInfoMap
					.entrySet()) {
				String term = entry.getKey();
				List<Integer> positionInfo = entry.getValue();
				Posting posting = new Posting(doc, fieldId, positionInfo);
				index.addPosting(term, posting);
			}
		}

		// save the document info
		index.saveDocument(doc);
	}
	
	public void setIndex(InvertedIndex invertedIndex) {
		postingCount = 0;
		this.index = invertedIndex;
	}
	
	public Map<String, List<Integer>> getPositonInfo(String text)
			throws Exception {
		Map<String, List<Integer>> map = new HashMap<String, List<Integer>>();
		TokenStream stream = analyzer.getTokenStream(text);

		int curPos = 0;
		String token;
		while ((token = stream.next()) != null) {
			List<Integer> positionList = map.get(token);
			if (positionList == null) {
				positionList = new ArrayList<Integer>();
				map.put(token, positionList);
			}
			positionList.add(curPos++);
		}
		return map;
	}
	
	/**
	 * get the amount of posting in the inverted index
	 * @return
	 */
	public long getIndexSize() {
		return index.getSize();
	}
	
	/**
	 * get the index of the writer
	 * @return
	 */
	public InvertedIndex getIndex() {
		return index;
	}

	public void close() {

	}

	public void commit() {

	}

	@Override
	public long getSizeInByte() {
		return index.getSizeInByte();
	}
}
